package com.atguigu.springsecurity.filter;

import com.alibaba.fastjson.JSON;

import com.atguigu.springsecurity.coutom.LoginUser;
import com.atguigu.springsecurity.utils.JwtHelper;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

/**
 * 登录拦截器最先拦截所有请求
 */

@Component
public class TokenLoginFilter extends OncePerRequestFilter {


//    @Resource
//    private RedisCache;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * @param request
     * @param response
     * @param filterChain
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, @NotNull HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            filterChain.doFilter(request, response);
            return;
        }
        // 如果说token有值的话
        // 获取用户id
        String subject;
        try {
            String userId = JwtHelper.getUserId(token);
            subject = userId;
        } catch (Exception e) {
            throw new RuntimeException("token非法");
        }

        // 从redis中根据userId获取信息
        String userId = subject;
        String redisKey = "login:" + userId;

        // value就是用户的信息
        String res = stringRedisTemplate.opsForValue().get(redisKey);
//        LoginUser res = redisCache.getCacheObject(redisKey);

        if (StringUtils.isEmpty(res)) {
            throw new RuntimeException("登录超时");
        }
        LoginUser loginUser = JSON.parseObject(res, LoginUser.class);

        // 获取到用户的权限
        // 存入SecurityContextHolder
        // 这里必须要使用三个参数的 因为里面第三个参数会设置认证状态为true
        Collection<? extends GrantedAuthority> authorities = loginUser.getAuthorities();
        // res表示用户的信息
        // 后面的就是凤爪弄权限的
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(res, null, authorities);
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);

        filterChain.doFilter(request, response);

    }
}
